#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__


#include "Spatial.h"
#include "Color.h"
#include "Vector2.h"

class Geometry : public Spatial
{
public:
	virtual ~Geometry();

	// vertex access
	unsigned int get_num_vertices() const;
	Vector3& vertex( unsigned int iv );
	const Vector3& vertex( unsigned int iv ) const;
	Vector3& vertices();
	const Vector3* vertices() const;

	// normal vector access
	Vector3& normal( unsigned int iv );
	const Vector3& normal( unsigned int iv ) const;
	Vector3* normals ();
    const Vector3* normals () const;

    // color access
	Color& color ( unsigned int iv );
    const Color& color ( unsigned int iv ) const;
    Color* colors ();
    const Color* colors () const;

    // texture coordinate access
    Vector2& texture ( unsigned int iv );
    const Vector2& texture ( unsigned int iv ) const;
    Vector2* textures ();
    const Vector2* textures () const;

    // bounding sphere access
    Bound& model_bound ();
    const Bound& model_bound () const;

    // geometric updates
    virtual void update_model_bound ();
    virtual void update_world_bound ();
    virtual void update_model_normals ();

protected:
    // Construction and destruction.  
    Geometry( unsigned int num_vertices, Vector3* vertex,
        Vector3* normal, Color* color, Vector2* texture );

    Geometry();

    void reconstruct ( unsigned int num_vertices );

    // The reconstruction allows you to change only individual arrays.  You
    // do this by passing in the current array pointers for any arrays you
    // want to preserve.
    void reconstruct( unsigned int num_vertices, Vector3* vertex,
        Vector3* normal, Color* color, Vector2* texture );

    // render state update
    virtual void update_render_state ( RenderState* state[] );

    // drawing
    virtual void draw ( Renderer& renderer );

    // vertices and attributes
    unsigned int m_num_vertices;
    Vector3* m_vertex;
    Vector3* m_normal;
    Color*   m_color;
    Vector2* m_texture;

    // model bound
    Bound m_bound;

    // render state
    RenderStatePtr m_state[RenderState::RS_MAX_STATE];
};

#include "Geometry.inl"

#endif